include(['com.unknown.Constants', 'com.unknown.Config', 'CanvasWrapper', 'constants.Screen'],
		
function(){
	
	declare('com.unknown.GameWindow');

	com.unknown.GameWindow = function(canvas, imageBucket){
		this.canvas = canvas;
		//this.c = canvas.getContext('2d');
		this.c = new CanvasWrapper(canvas.getContext('2d'));
		
		this.loadedimages = [];
		this.imageBucket = $(imageBucket);
		
		this.backgrounds = [];
		this.billboards = [];
	
		this.renderers = [];
		
		this.entities = [];
		this.totalFrames = 0;
		this.skip = 0;

		this.requestAnimationFrame = window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame;
		this.requestAnimationFrame = this.requestAnimationFrame || setTimeout

		var __scope = this;
        var framerate = null;

		window.onblur = function(){
			//__scope.paused = true;
			//$('#spinner').show();
		}

		this.start = function(){
			var gw = this;
            $(function(){
                gw.framerate = document.getElementById('framerate');
            });

			this.requestAnimationFrame.apply(window, [function(){
				gw.mainLoop();
			}, 0]);
		};
		
		this.addEntity = function(entity){
			//var e = new com.unknown.Entity( this.player.img );
			//e.name = name;
			this.entities[entity.name] = entity;
		};
		
		this.orientationChanged = function(){
			this.c.scale(1, 1);
		};
	
		this.createImage = function(src){
			if(!this.loadedimages[src]){
				var img = document.createElement('img');
				$(img).attr('src', src);
				this.imageBucket.append(img);
				this.loadedimages[src] = {img: img, count: 1};
			}else{
				this.loadedimages[src].count++;
			}
			return this.loadedimages[src];
		};

        this.timestamp = 0;
        this.lastUpdated = 0;
        this.lastFramerate = 0;
		this.mainLoop = function(){
			if( this.paused ) return;
			//this.canvas.width = this.canvas.width			
			//this.c.clearRect( 0, 0, this.canvas.width, this.canvas.height);
			
			this.totalFrames++;

            this.timestamp = new Date().getTime();
            //35 updates a second = 1000/35 ~= 29
            if( this.timestamp - this.lastUpdated > 29 ){
                this.mainUpdate();
                this.lastUpdated = this.timestamp;
            }
            if( this.framerate && (this.timestamp - this.lastFramerate > 5000) ){
                this.framerate.innerHTML = 'Frames: ' + (__scope.totalFrames/5) + 'fps';
                this.totalFrames = 0;
                this.lastFramerate = this.timestamp;
            }

			//this.clearObjects();
			this.c.clear();
			
			this.render();
			
			var gw = this;
			this.requestAnimationFrame.apply(window,[function(){
				gw.mainLoop();
			}, 0]);
		};
		this.mainUpdate = function(){
			var gw = this;
			iterate(this.entities, function(item){
				if( item.update ){
					item.update(gw);
				}
			});
		};	
		this.clearObjects = function(){
			var c = this.c;
			iterate(this.entities, function(entity){
				if( entity.clearRect ){
					var rect = entity.clearRect();
					c.clearRect(rect.x, rect.y, rect.width, rect.height);
				}
			});
		};		
		this.render = function(){
			for(var e in this.renderers ){
				var renderer = this.renderers[e];
				if(renderer && !(typeof(renderer) == 'function' )){
					var pass = false;
					try{
						this.c.save();
						renderer.render(this);
						pass = true;
					}catch(e){
						console.error(e);
					}finally{
						if( !pass ){
							console.error("Removing renderer: " + renderer.name);
							this.renderers[e] = null;
						}
						this.c.restore();
					}				
				}
			}
			var c = this.c;
			iterate(this.billboards, function(billboard){
				billboard.draw(c);
			});
			
		};	
		
		this.normalize = function(vec2){
			if( vec2.x > this.canvas.width - 60 ) 
				vec2.x = this.canvas.width - 60;
			if( vec2.x < 15 ) 
				vec2.x = 15;
			
			if( vec2.y > this.canvas.height - 60 ) 
				vec2.y = this.canvas.height - 60;
			if( vec2.y < 15 ) 
				vec2.y = 15;
			
			return vec2;
		};
		
		this.draw = function(src, x, y){
            var img = this.createImage(src);
			if(img.img.width == 0 ) return;
			
			if( arguments.length == 9 ){
				this.c.drawImage(img.img, arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7], arguments[8]);
			}else{
				this.c.drawImage(img.img, x, y);
			}
		};
		
		this.moveBackground = function(x, y){
			for(var index=0; index < this.backgrounds.length; index++){
				this.backgrounds[index].move(x,y);
			}
		};

        this.containsPoint = function(point){
            return point.x > 0 &&
            point.y > 0 &&
            point.x < (this.canvas.width - constants.Screen.TOTAL_MARGIN_WIDTH) &&
            point.y < (this.canvas.height - constants.Screen.TOTAL_MARGIN_HEIGHT);
        };
	}
	

});